package cn.enjoyedu.nettybasic.serializable.msgpack2;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.LineBasedFrameDecoder;


import java.net.InetSocketAddress;

public class ClientMsgPackEcho {
    private final String host;

    public ClientMsgPackEcho(String host) {
        this.host = host;
    }

    public void start() throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            final Bootstrap b = new Bootstrap();
            b.group(group)/*将线程组传入*/
                    .channel(NioSocketChannel.class)/*指定使用NIO进行网络传输*/
                    /*配置要连接服务器的IP地址和端口*/
                    .remoteAddress(new InetSocketAddress(host, ServerMsgPackEcho.PORT))
                    .handler(new ChannelInitializerImp());
            ChannelFuture f = b.connect().sync();
            System.out.println("已连接到服务器、、、、");
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }

    }
    private static class ChannelInitializerImp extends ChannelInitializer<Channel>{
        /**
         * This method will be called once the {@link Channel} was registered. After the method returns this instance
         * will be removed from the {@link ChannelPipeline} of the {@link Channel}.
         *
         * @param ch the {@link Channel} which was registered.
         * @throws Exception is thrown if an error occurs. In that case it will be handled by
         *                   {@link #exceptionCaught(ChannelHandlerContext, Throwable)} which will by default close
         *                   the {@link Channel}.
         */
        @Override
        protected void initChannel(Channel ch) throws Exception {
            /*告诉netty，计算报文的长度，然后作为报文头加在前面*/
            ch.pipeline().addLast(new LengthFieldPrepender(2));
            /*对服务器的应答也要解码，解决粘包半包*/
            ch.pipeline().addLast(new LineBasedFrameDecoder(1024));
            /*对我们发的数据做编码-序列化*/
            ch.pipeline().addLast(new MsgPackEncode());
            ch.pipeline().addLast(new MsgPackClientHandler(5));

        }
    }

    public static void main(String[] args) throws InterruptedException {
        new ClientMsgPackEcho("127.0.0.1").start();
    }
}
